import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;

import model.DocumentsManager;
import model.arbolBSharp.ArbolBSharpException;
import model.extras.FileExists;
import model.CompressionManager;
import model.registro.RegistroDocumentosDisponibles;


public class TheSpeaker {

	/**
	 * @param args
	 * @throws IOException 
	 */
	
	public static int MostrarMenuPrincipal(BufferedReader input){
		int option=0;
		
		System.out.println("The Speaker");
		System.out.println("=== =======");
		System.out.println("");
		System.out.println("1- Carga de documentos (sin grabación de audio)");
		System.out.println("2- Carga de documentos (con grabación de audio)");
		System.out.println("3- Listar documentos indexados");
		System.out.println("4- Reproducción de documento");
		System.out.println("5- Consulta por términos");
		System.out.println("6- Salir");
		System.out.println("");
		System.out.print("Ingrese un valor: ");
		try{
			option = Integer.parseInt(input.readLine());
		}
		catch (Exception exOpcion){
			System.out.println("ERROR: Opción inválida.");
			System.out.println("");
			return 0;
		}
	
		if ((option<1) || (option>6)){
			System.out.println("ERROR: Opción inválida.");
			System.out.println("");
			return 0;			
		}
		else
			return option;
	}
	
	public static void MostrarUso(){ 
		
		System.out.println("USO: TheSpeaker -operación -algoritmo -entrada <nombreArchivo>");
		System.out.println("Operaciones:");
		System.out.println("-c\tComprimir archivo.");
		System.out.println("-d\tDescomprimir archivo.");
		System.out.println("Algoritmos:");
		System.out.println("-a\tUtilza el algoritmo aritmético.");
		System.out.println("-l\tUtiliza LZP.");
		System.out.println("-p\tUtiliza PPMC.");
		System.out.println("Ejemplos:");
		System.out.println("TheSpeaker -cl -entrada ejemplo.jar");
		System.out.println("TheSpeaker -d -l -entrada ejemplo.lzp");
	}
	
	public static void main(String[] args) throws IOException, ArbolBSharpException {
		
		//Comprobacion de la cantidad de argumentos, para saber en que modo ejecutar el programa.
		if (args.length!=0)
		{
			//Modo terminal, para aplicar compresores a archivos externos.			
	        int i = 0, j;
	        int cantOp=0;
	        int cantAl=0;
	        int cantAr=0;
	        
	        String argumento;
	        char opcion;
	        boolean error=false;
	        
	        char optOp='c';
	        char optAl='a';
	        String rutaArchivo = "";

	        while (i < args.length && args[i].startsWith("-")) {
	            argumento = args[i++];

	            if (argumento.equals("-entrada")) {
	            	cantAr++;
	                if (i < args.length)
	                	rutaArchivo = args[i++];
	                else
	                {
	                	error=true;
	                	System.out.println("ERROR: La opción \"-entrada\" requiere un nombre de archivo.");
	                }
	            }
	            else {
	                for (j = 1; j < argumento.length(); j++) {
	                    opcion = argumento.charAt(j);
	                    
	                    if ((opcion=='c') || (opcion=='d')) {	                    	
	                    	cantOp++;
	                    	optOp=opcion; 	
	                    }
	                    else
	                    {
		                    if ((opcion=='a') || (opcion=='l') || (opcion=='p')) {		                    	
		                    	cantAl++;
		                    	optAl=opcion;	                    	
		                    }
		                    else
		                    {
		                    	error=true;
		                        System.out.println("ERROR: Opción inválida \"-"+ opcion + "\".");
		                    }
	                    }
	                }
	            }
	        }
	          
	        if (i<args.length){
	        	System.out.println("ERROR: Opción inválida \""+ args[i] + "\".");
        		error=true;	        	
	        }
	        
	        if (!error){
	        	if (cantOp!=1){
	        		System.out.println("ERROR: Operación no especificada o ambigua.");
	        		error=true;
	        	}
	        	if (cantAl!=1){
	        		System.out.println("ERROR: Algoritmo de compresión no especificado o ambiguo.");
	        		error=true;
	        	}	
	        	if (cantAr!=1){
	                System.out.println("ERROR: Archivo de salida no especificado o ambiguo.");
	                error=true;
	        	}	        	    
	        }
	        
		    if (error){
		    	System.out.println("");
		    	MostrarUso();
		    }
		    
		    if ((cantOp==1) && (cantAl==1) && (cantAr==1) && (!error)){
		    	try {		    		
				    if (FileExists.verifyPath(rutaArchivo)){
				    	
						File dir = new File("sistema");  
						dir.mkdir(); 
				    	
				    	if (CompressionManager.ProcesarCMD(optOp,optAl,rutaArchivo)==-1)
				    		System.out.println("INFORMACION: Archivo vacío. Ignorado.");
				    }
				    else
				    	System.out.println("ERROR: El archivo no fue encontrado.");		    				
		    	}
		    	catch (Exception e) {
		    		System.out.println(e.toString());	
		    	}		    	
		    }		    
		}
		else			
		{
			//Modo interactivo, TheSpeaker.
			int option = 0;
			boolean grabarAudio = true;
			BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
			File dir = new File("sistema");  
			dir.mkdir(); 
			DocumentsManager documentsManager = new DocumentsManager();
			while (option != 6) {
				option = MostrarMenuPrincipal(input); 
				try{
					switch (option) {
					case 1:
						grabarAudio=false;
					case 2:
						String subOption = "s";
						String pathDoc;
						String OpCompresionString;
						
						int cantDocs=0;
						boolean indexar=false;
						while (subOption.compareTo("s") == 0) {
							boolean yaExiste=false;
							System.out.print("Ubicación del archivo de texto: ");
							pathDoc = input.readLine();
							if (FileExists.verifyPath(pathDoc)) {	

								ArrayList<RegistroDocumentosDisponibles> Temp = new ArrayList<RegistroDocumentosDisponibles>();
								Temp=documentsManager.GetLoadedDocuments();				
								for (int i=0; i<Temp.size();i++)
									if (Temp.get(i).getNombreDocumento().equals(FileExists.CleanPath(pathDoc)))
										yaExiste=true;
								
								if (!yaExiste) {
									
									if (documentsManager.CargarTextoDocumento(pathDoc,grabarAudio) == 0) {
										indexar=true;
										cantDocs++;
										
										System.out.print("Documento cargado. Seleccione método de compresión (a/l/p/n): ");
										OpCompresionString = input.readLine();
										OpCompresionString = OpCompresionString.toLowerCase();
						
										int OpCompresionInt=0;
										if (OpCompresionString.equals("a")) OpCompresionInt=1;
										if (OpCompresionString.equals("l")) OpCompresionInt=2;
										if (OpCompresionString.equals("p")) OpCompresionInt=3;
										
										documentsManager.ComprimirDocumento(pathDoc,OpCompresionInt);
																				
									}
									else
									{
										System.out.println("INFORMACION: Archivo vacío. Ignorado.");
										System.out.println("");									
									}
								}
								else {
									System.out.println("INFORMACION: Un archivo con ese nombre ya fue cargado.");
									System.out.println("");
								}							
							} else {
								System.out.println("ERROR: El archivo no fue encontrado.");
								System.out.println("");
							}
											
							System.out.print("Desea agregar otro documento? (s/n): ");
							subOption = input.readLine();
						}
						if (indexar) {
							System.out.println("INFORMACION: Indexando. Por favor aguarde...");
							documentsManager.CreateFTRSWorkFiles();	
							System.out.println("INFORMACION: "+cantDocs+" documento(s) indexado(s). Total de documentos indexados: "+documentsManager.GetCantDocumentos()+".\n");
						}
						grabarAudio=true;
						break;							
					case 3:
						if (documentsManager.GetCantDocumentos()==0){
							System.out.println("INFORMACION: No hay documentos cargados.");
							System.out.println("");
						}
						else
						{	
							ArrayList<RegistroDocumentosDisponibles> Temp = new ArrayList<RegistroDocumentosDisponibles>();
							Temp=documentsManager.GetLoadedDocuments();
							
							System.out.println("Hay "+Temp.size()+" documento(s) indexado(s):");
							for (int i=0; i<Temp.size();i++){														
								switch (Temp.get(i).getAlgoritmoCompresion()) {
									case 1:
										System.out.println("Nombre del documento: \""+Temp.get(i).getNombreDocumento()+"\". Algoritmo utilizado: \"ARITMETICO\". Grado de compresion: "+Temp.get(i).getGradoCompresion()+"%.");
										break;
									case 2:
										System.out.println("Nombre del documento: \""+Temp.get(i).getNombreDocumento()+"\". Algoritmo utilizado: \"LZP\". Grado de compresion: "+Temp.get(i).getGradoCompresion()+"%.");
										break;
									case 3:
										System.out.println("Nombre del documento: \""+Temp.get(i).getNombreDocumento()+"\". Algoritmo utilizado: \"PPMC\". Grado de compresion: "+Temp.get(i).getGradoCompresion()+"%.");
										break;
									default:
										System.out.println("Nombre del documento: \""+Temp.get(i).getNombreDocumento()+"\". Algoritmo utilizado: \"NINGUNO\".");
									break;								
								}
							}
							System.out.println("");
						}
						break;
					case 4:
						if (documentsManager.GetCantDocumentos()==0){
							System.out.println("INFORMACION: No hay documentos cargados.");
							System.out.println("");
						}
						else
						{	
							System.out.print("Ingrese el nombre de uno de los documentos disponibles para reproducir: ");
							subOption = input.readLine();
							documentsManager.ReadDocument(subOption);
						}
						break;
					case 5:
						if (documentsManager.indiceCreado()){
							System.out.print("Términos a buscar: ");
							String query = input.readLine();
							documentsManager.resolverConsulta(query);
						}
						else
						{
							System.out.println("INFORMACION: El índice no ha sido creado. Debe cargar documentos antes de utilizar esta opción.");
							System.out.println("");
						}
						break;
					default:
						break;
					}
				}
				catch(Exception e){					
					System.out.println(e.toString());					
				}			
			}
			documentsManager.CloseFiles();
		}
	}
}
